package proyecto.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import javax.sql.DataSource;
import proyecto.excepcion.DAOExcepcion;
import proyecto.modelo.Requerimiento;
import proyecto.modelo.Area;
import proyecto.modelo.ClaseFormacion;
import proyecto.modelo.NivelFormacion;
import proyecto.modelo.Profesion;
import proyecto.modelo.Empleado;


public class RequerimientoDAOImpl extends BaseDAO implements RequerimientoDAO {

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public Collection<Requerimiento> buscarPorCodigo(int codigo)
            throws DAOExcepcion {
        String query = "SELECT 	REQ_NUMERO, are.ARE_CODIGO, are.ARE_DESCRIPCION, cla.TIPEST_CODIGO," +
	" cla.TIPEST_DESCRIPCION, " +
	" niv.NIVFOR_CODIGO, niv.NIVFOR_DESCRIPCION," +
	" pro.PRO_CODIGO, pro.PRO_DESCRIPCION, emp.EMP_CODIGO, emp.EMP_NOMBRE," +
	" emp.EMP_APELLIDOPATERNO, emp.EMP_APELLIDOMATERNO, REQ_FECHAREGISTRO, REQ_TIPOURGENCIA, REQ_EDADMINIMA, " +
	" REQ_EDADMAXIMA, REQ_SEXO, REQ_ANIOEXPERIENCIA, REQ_ESTADOLABORAL," +
	" REQ_ESTADO, REQ_SUSTENTO, REQ_SUSTENTOANUL" +
	" FROM " +
	" requerimiento req, AREA are, claseformacion cla, " +
	" nivelformacion niv, profesion pro, empleado emp" +
	" WHERE req.ARE_CODIGO = are.ARE_CODIGO" +
	" AND req.TIPEST_CODIGO = cla.TIPEST_CODIGO" +
	" AND req.NIVFOR_CODIGO = niv.NIVFOR_CODIGO" +
	" AND req.PRO_CODIGO = pro.PRO_CODIGO" +
	" AND req.EMP_CODIGO = emp.EMP_CODIGO" +
        " AND REQ_NUMERO like ?";


        Collection<Requerimiento> lista = new ArrayList<Requerimiento>();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setInt(1, codigo);

            rs = stmt.executeQuery();
            while (rs.next()) {
                Requerimiento vo = new Requerimiento();
                vo.setReq_Numero(rs.getInt("REQ_NUMERO"));
                vo.setReq_TipoUrgencia(rs.getString("REQ_TIPOURGENCIA"));
                vo.setReq_EdadMaxima(rs.getInt("REQ_EDADMAXIMA"));
                vo.setReq_EdadMinima(rs.getInt("REQ_EDADMINIMA"));
                vo.setReq_Sexo(rs.getString("REQ_SEXO"));
                vo.setReq_AnioExperiencia(rs.getInt("REQ_ANIOEXPERIENCIA"));
                vo.setReq_EstadoLaboral(rs.getString("REQ_ESTADOLABORAL"));
                vo.setReq_Estado(rs.getString("REQ_ESTADO"));
                vo.setReq_Sustento(rs.getString("REQ_SUSTENTO"));
                vo.setReq_SustentoAnul(rs.getString("REQ_SUSTENTOANUL"));
                //vo.setEmp_FechaIngreso(rs.getDate("REQ_FECHAREGISTRO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                ClaseFormacion claseFormacion = new ClaseFormacion();
                claseFormacion.setTipEst_Codigo(rs.getInt("TIPEST_CODIGO"));
                claseFormacion.setTipEst_Descripcion(rs.getString("TIPEST_DESCRIPCION"));

                NivelFormacion nivelFormacion = new NivelFormacion();
                nivelFormacion.setNivFor_Codigo(rs.getInt("NIVFOR_CODIGO"));
                nivelFormacion.setNivFor_Descripcion(rs.getString("NIVFOR_DESCRIPCION"));

                Profesion profesion = new Profesion();
                profesion.setPro_Codigo(rs.getInt("PRO_CODIGO"));
                profesion.setPro_Descripcion(rs.getString("PRO_DESCRIPCION"));


                Empleado empleado = new Empleado();
                empleado.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                empleado.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                empleado.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                empleado.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));


                vo.setArea(area);
                vo.setClaseFormacion(claseFormacion);
                vo.setNivelFormacion(nivelFormacion);
                vo.setProfesion(profesion);
                vo.setEmpleado(empleado);

                lista.add(vo);
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        System.out.println(lista.size());
        return lista;
    }

    public Requerimiento insertar(Requerimiento vo) throws DAOExcepcion {
        String query = "INSERT INTO requerimiento " +
	" (REQ_NUMERO, " +
	" ARE_CODIGO, " +
	" TIPEST_CODIGO, " +
	" NIVFOR_CODIGO, " +
	" PRO_CODIGO, " +
	" EMP_CODIGO,  " +
	" REQ_TIPOURGENCIA, " +
	" REQ_EDADMINIMA, " +
	" REQ_EDADMAXIMA, " +
	" REQ_SEXO, " +
	" REQ_ANIOEXPERIENCIA, " +
	" REQ_ESTADOLABORAL, " +
	" REQ_SUSTENTO" +
	" )" +
	" VALUES" +
	" (?, ?, ?, ?, ?,  ?, ?, ?, ?, ?, ?, ?, ?" +
	" );";
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setInt(1, vo.getReq_Numero());
            stmt.setInt(2, vo.getArea().getAre_Codigo());
            stmt.setInt(3, vo.getClaseFormacion().getTipEst_Codigo());
            stmt.setInt(4, vo.getNivelFormacion().getNivFor_Codigo());
            stmt.setInt(5, vo.getProfesion().getPro_Codigo());
            stmt.setString(6, vo.getEmpleado().getEmp_Codigo());
            stmt.setString(7, vo.getReq_TipoUrgencia());
            stmt.setInt(8, vo.getReq_EdadMinima());
            stmt.setInt(9, vo.getReq_EdadMaxima());
            stmt.setString(10, vo.getReq_Sexo());
            stmt.setInt(11, vo.getReq_AnioExperiencia());
            stmt.setString(12, vo.getReq_EstadoLaboral());
            stmt.setString(13, vo.getReq_Sustento());
            //stmt.setString(14, vo.getReq_Estado());


            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo insertar");
            }
            // Obtener el ultimo id
            int id = 0;
            query = "SELECT LAST_INSERT_ID()";
            stmt = con.prepareStatement(query);
            rs = stmt.executeQuery();
            if (rs.next()) {
                id = rs.getInt(1);
            }

        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public Requerimiento obtener(int codigo) throws DAOExcepcion {
        Requerimiento vo = new Requerimiento();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            String query = "SELECT 	REQ_NUMERO, are.ARE_CODIGO, are.ARE_DESCRIPCION, cla.TIPEST_CODIGO," +
	" cla.TIPEST_DESCRIPCION, " +
	" niv.NIVFOR_CODIGO, niv.NIVFOR_DESCRIPCION," +
	" pro.PRO_CODIGO, pro.PRO_DESCRIPCION, emp.EMP_CODIGO, emp.EMP_NOMBRE," +
	" emp.EMP_APELLIDOPATERNO, emp.EMP_APELLIDOMATERNO, REQ_FECHAREGISTRO, REQ_TIPOURGENCIA, REQ_EDADMINIMA, " +
	" REQ_EDADMAXIMA, REQ_SEXO, REQ_ANIOEXPERIENCIA, REQ_ESTADOLABORAL," +
	" REQ_ESTADO, REQ_SUSTENTO, REQ_SUSTENTOANUL" +
	" FROM " +
	" requerimiento req, AREA are, claseformacion cla, " +
	" nivelformacion niv, profesion pro, empleado emp" +
	" WHERE req.ARE_CODIGO = are.ARE_CODIGO" +
	" AND req.TIPEST_CODIGO = cla.TIPEST_CODIGO" +
	" AND req.NIVFOR_CODIGO = niv.NIVFOR_CODIGO" +
	" AND req.PRO_CODIGO = pro.PRO_CODIGO" +
	" AND req.EMP_CODIGO = emp.EMP_CODIGO" +
                    " AND REQ_NUMERO = ?";
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setInt(1, codigo);
            rs = stmt.executeQuery();
            if (rs.next()) {
                vo.setReq_Numero(rs.getInt("REQ_NUMERO"));
                vo.setReq_TipoUrgencia(rs.getString("REQ_TIPOURGENCIA"));
                vo.setReq_EdadMaxima(rs.getInt("REQ_EDADMAXIMA"));
                vo.setReq_EdadMinima(rs.getInt("REQ_EDADMINIMA"));
                vo.setReq_Sexo(rs.getString("REQ_SEXO"));
                vo.setReq_AnioExperiencia(rs.getInt("REQ_ANIOEXPERIENCIA"));
                vo.setReq_EstadoLaboral(rs.getString("REQ_ESTADOLABORAL"));
                vo.setReq_Estado(rs.getString("REQ_ESTADO"));
                vo.setReq_Sustento(rs.getString("REQ_SUSTENTO"));
                vo.setReq_SustentoAnul(rs.getString("REQ_SUSTENTOANUL"));
                //vo.setEmp_FechaIngreso(rs.getDate("REQ_FECHAREGISTRO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                ClaseFormacion claseFormacion = new ClaseFormacion();
                claseFormacion.setTipEst_Codigo(rs.getInt("TIPEST_CODIGO"));
                claseFormacion.setTipEst_Descripcion(rs.getString("TIPEST_DESCRIPCION"));

                NivelFormacion nivelFormacion = new NivelFormacion();
                nivelFormacion.setNivFor_Codigo(rs.getInt("NIVFOR_CODIGO"));
                nivelFormacion.setNivFor_Descripcion(rs.getString("NIVFOR_DESCRIPCION"));

                Profesion profesion = new Profesion();
                profesion.setPro_Codigo(rs.getInt("PRO_CODIGO"));
                profesion.setPro_Descripcion(rs.getString("PRO_DESCRIPCION"));


                Empleado empleado = new Empleado();
                empleado.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                empleado.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                empleado.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                empleado.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));


                vo.setArea(area);
                vo.setClaseFormacion(claseFormacion);
                vo.setNivelFormacion(nivelFormacion);
                vo.setProfesion(profesion);
                vo.setEmpleado(empleado);
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public void eliminar(int codigo) throws DAOExcepcion {
        String query = "DELETE FROM Requerimiento WHERE REQ_NUMERO=?";
        Connection con = null;
        PreparedStatement stmt = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);
            stmt.setInt(1, codigo);
            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo eliminar");
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
    }

    public Requerimiento actualizar(Requerimiento vo) throws DAOExcepcion {
        String query = "UPDATE requerimiento  " +
	" SET  " +
	" ARE_CODIGO = ? ,  " +
	" TIPEST_CODIGO = ? ,  " +
	" NIVFOR_CODIGO = ? ,  " +
	" PRO_CODIGO = ?,  " +
	" EMP_CODIGO = ? ,  " +
	" REQ_TIPOURGENCIA = ? ,  " +
	" REQ_EDADMINIMA = ? ,  " +
	" REQ_EDADMAXIMA = ?,  " +
	" REQ_SEXO = ? ,  " +
	" REQ_ANIOEXPERIENCIA = ? ,  " +
	" REQ_ESTADOLABORAL = ? ,  " +
	" REQ_ESTADO = ? ,  " +
	" REQ_SUSTENTO = ? " +
	" WHERE " +
	" REQ_NUMERO = ? ;";
        Connection con = null;
        PreparedStatement stmt = null;
        try {
            con = dataSource.getConnection();
            stmt = con.prepareStatement(query);


            stmt.setInt(1, vo.getArea().getAre_Codigo());
            stmt.setInt(2, vo.getClaseFormacion().getTipEst_Codigo());
            stmt.setInt(3, vo.getNivelFormacion().getNivFor_Codigo());
            stmt.setInt(4, vo.getProfesion().getPro_Codigo());
            stmt.setString(5, vo.getEmpleado().getEmp_Codigo());
            stmt.setString(6, vo.getReq_TipoUrgencia());
            stmt.setInt(7, vo.getReq_EdadMinima());
            stmt.setInt(8, vo.getReq_EdadMaxima());
            stmt.setString(9, vo.getReq_Sexo());
            stmt.setInt(10, vo.getReq_AnioExperiencia());
            stmt.setString(11, vo.getReq_EstadoLaboral());
            stmt.setString(12, vo.getReq_Estado());
            stmt.setString(13, vo.getReq_Sustento());

            stmt.setInt(14, vo.getReq_Numero());

            int i = stmt.executeUpdate();
            if (i != 1) {
                throw new SQLException("No se pudo actualizar");
            }
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return vo;
    }

    public Collection<Requerimiento> listar() throws DAOExcepcion {
        Collection<Requerimiento> lista = new ArrayList<Requerimiento>();
        Connection con = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();
            String query = "SELECT REQ_NUMERO, are.ARE_CODIGO, are.ARE_DESCRIPCION, cla.TIPEST_CODIGO," +
	" cla.TIPEST_DESCRIPCION, " +
	" niv.NIVFOR_CODIGO, niv.NIVFOR_DESCRIPCION," +
	" pro.PRO_CODIGO, pro.PRO_DESCRIPCION, emp.EMP_CODIGO, emp.EMP_NOMBRE," +
	" emp.EMP_APELLIDOPATERNO, emp.EMP_APELLIDOMATERNO, REQ_FECHAREGISTRO, REQ_TIPOURGENCIA, REQ_EDADMINIMA, " +
	" REQ_EDADMAXIMA, REQ_SEXO, REQ_ANIOEXPERIENCIA, REQ_ESTADOLABORAL," +
	" REQ_ESTADO, REQ_SUSTENTO, REQ_SUSTENTOANUL" +
	" FROM " +
	" requerimiento req, AREA are, claseformacion cla, " +
	" nivelformacion niv, profesion pro, empleado emp" +
	" WHERE req.ARE_CODIGO = are.ARE_CODIGO" +
	" AND req.TIPEST_CODIGO = cla.TIPEST_CODIGO" +
	" AND req.NIVFOR_CODIGO = niv.NIVFOR_CODIGO" +
	" AND req.PRO_CODIGO = pro.PRO_CODIGO" +
	" AND req.EMP_CODIGO = emp.EMP_CODIGO";
            stmt = con.prepareStatement(query);
            rs = stmt.executeQuery();
            while (rs.next()) {
                Requerimiento vo = new Requerimiento();
                vo.setReq_Numero(rs.getInt("REQ_NUMERO"));
                vo.setReq_TipoUrgencia(rs.getString("REQ_TIPOURGENCIA"));
                vo.setReq_EdadMaxima(rs.getInt("REQ_EDADMAXIMA"));
                vo.setReq_EdadMinima(rs.getInt("REQ_EDADMINIMA"));
                vo.setReq_Sexo(rs.getString("REQ_SEXO"));
                vo.setReq_AnioExperiencia(rs.getInt("REQ_ANIOEXPERIENCIA"));
                vo.setReq_EstadoLaboral(rs.getString("REQ_ESTADOLABORAL"));
                vo.setReq_Sustento(rs.getString("REQ_SUSTENTO"));
                //vo.setReq_SustentoAnul(rs.getString("REQ_SUSTENTOANUL"));
                //vo.setReq_Estado(rs.getString("REQ_ESTADO"));
                //vo.setEmp_FechaIngreso(rs.getDate("REQ_FECHAREGISTRO"));

                Area area = new Area();
                area.setAre_Codigo(rs.getInt("ARE_CODIGO"));
                area.setAre_Descripcion(rs.getString("ARE_DESCRIPCION"));

                ClaseFormacion claseFormacion = new ClaseFormacion();
                claseFormacion.setTipEst_Codigo(rs.getInt("TIPEST_CODIGO"));
                claseFormacion.setTipEst_Descripcion(rs.getString("TIPEST_DESCRIPCION"));

                NivelFormacion nivelFormacion = new NivelFormacion();
                nivelFormacion.setNivFor_Codigo(rs.getInt("NIVFOR_CODIGO"));
                nivelFormacion.setNivFor_Descripcion(rs.getString("NIVFOR_DESCRIPCION"));

                Profesion profesion = new Profesion();
                profesion.setPro_Codigo(rs.getInt("PRO_CODIGO"));
                profesion.setPro_Descripcion(rs.getString("PRO_DESCRIPCION"));


                Empleado empleado = new Empleado();
                empleado.setEmp_Codigo(rs.getString("EMP_CODIGO"));
                empleado.setEmp_Nombre(rs.getString("EMP_NOMBRE"));
                empleado.setEmp_ApellidoPaterno(rs.getString("EMP_APELLIDOPATERNO"));
                empleado.setEmp_ApellidoMaterno(rs.getString("EMP_APELLIDOMATERNO"));


                vo.setArea(area);
                vo.setClaseFormacion(claseFormacion);
                vo.setNivelFormacion(nivelFormacion);
                vo.setProfesion(profesion);
                vo.setEmpleado(empleado);

                lista.add(vo);
            }

        } catch (SQLException e) {
            System.err.println(e.getMessage());
            throw new DAOExcepcion(e.getMessage());
        } finally {
            this.cerrarResultSet(rs);
            this.cerrarStatement(stmt);
            this.cerrarConexion(con);
        }
        return lista;
    }
}
